﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

namespace Tools
{
    /// <summary>
    /// 数据读写工具类（支持本地文件、PlayerPrefs、网络资源等操作）
    /// </summary>
    public static class RWS
    {
        private static MonoBehaviour _coroutineRunner;

        /// <summary>
        /// 设置协程运行器（需在使用异步方法前调用）
        /// </summary>
        public static void SetCoroutineRunner(MonoBehaviour runner)
        {
            _coroutineRunner = runner ?? throw new ArgumentNullException(nameof(runner), "协程运行器不能为null");
        }

        #region PlayerPrefs 操作
        /// <summary>
        /// 通过PlayerPrefs保存字符串数据
        /// </summary>
        public static void PlayerPrefsSaveData(string dataKey, string data)
        {
            if (string.IsNullOrEmpty(dataKey))
            {
                Debug.LogError("数据键不能为空");
                return;
            }
            PlayerPrefs.SetString(dataKey, data);
            PlayerPrefs.Save(); // 立即保存到磁盘
        }

        /// <summary>
        /// 通过PlayerPrefs读取字符串数据
        /// </summary>
        public static string PlayerPrefsLoadData(string dataKey)
        {
            if (string.IsNullOrEmpty(dataKey))
            {
                Debug.LogError("数据键不能为空");
                return null;
            }
            return PlayerPrefs.HasKey(dataKey) ? PlayerPrefs.GetString(dataKey) : null;
        }
        #endregion

        #region 文本文件操作
        /// <summary>
        /// 读取文本文件（默认UTF-8编码）
        /// </summary>
        public static string TextFileRead(string path, Encoding encoding = null)
        {
            if (string.IsNullOrEmpty(path))
            {
                Debug.LogError("文件路径不能为空");
                return string.Empty;
            }

            if (!File.Exists(path))
            {
                Debug.LogWarning($"文件不存在: {path}");
                return string.Empty;
            }

            try
            {
                encoding ??= Encoding.UTF8;
                return File.ReadAllText(path, encoding);
            }
            catch (IOException e)
            {
                Debug.LogError($"读取文件失败: {e.Message}，路径: {path}");
                return string.Empty;
            }
        }

        /// <summary>
        /// 写入文本文件（默认UTF-8编码）
        /// </summary>
        public static void TextFileWrite(string path, string data, Encoding encoding = null)
        {
            if (string.IsNullOrEmpty(path))
            {
                Debug.LogError("文件路径不能为空");
                return;
            }

            try
            {
                // 确保目录存在
                string directory = Path.GetDirectoryName(path);
                if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                encoding ??= Encoding.UTF8;
                File.WriteAllText(path, data, encoding);
            }
            catch (Exception ex)
            {
                Debug.LogError($"写入文件失败: {ex.Message}，路径: {path}");
            }
        }
        #endregion

        #region 网络资源加载（异步）
        /// <summary>
        /// 异步加载网络图片为Texture2D
        /// </summary>
        public static void LoadRemoteTextureAsync(string url, Action<Texture2D, string> callback)
        {
            ValidateCoroutineRunner();
            _coroutineRunner.StartCoroutine(LoadRemoteTextureCoroutine(url, callback));
        }

        private static IEnumerator LoadRemoteTextureCoroutine(string url, Action<Texture2D, string> callback)
        {
            if (string.IsNullOrEmpty(url))
            {
                callback?.Invoke(null, "URL为空");
                yield break;
            }

            using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(url))
            {
                yield return request.SendWebRequest();

                if (request.result == UnityWebRequest.Result.Success)
                {
                    Texture2D texture = DownloadHandlerTexture.GetContent(request);
                    callback?.Invoke(texture, null);
                }
                else
                {
                    string error = $"加载失败: {request.error}，URL: {url}";
                    Debug.LogError(error);
                    callback?.Invoke(null, error);
                }
            }
        }

        /// <summary>
        /// 异步加载网络文本
        /// </summary>
        public static void LoadRemoteTextAsync(string url, Action<string, string> callback)
        {
            ValidateCoroutineRunner();
            _coroutineRunner.StartCoroutine(LoadRemoteTextCoroutine(url, callback));
        }

        private static IEnumerator LoadRemoteTextCoroutine(string url, Action<string, string> callback)
        {
            if (string.IsNullOrEmpty(url))
            {
                callback?.Invoke(null, "URL为空");
                yield break;
            }

            using (UnityWebRequest request = UnityWebRequest.Get(url))
            {
                yield return request.SendWebRequest();

                if (request.result == UnityWebRequest.Result.Success)
                {
                    callback?.Invoke(request.downloadHandler.text, null);
                }
                else
                {
                    string error = $"加载失败: {request.error}，URL: {url}";
                    Debug.LogError(error);
                    callback?.Invoke(null, error);
                }
            }
        }
        #endregion

        #region 本地文件与字节流转换
        /// <summary>
        /// 将文件读取为字节数组
        /// </summary>
        public static byte[] FileToBytes(string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                Debug.LogError("文件路径不能为空");
                return null;
            }

            if (!File.Exists(filePath))
            {
                Debug.LogError($"文件不存在: {filePath}");
                return null;
            }

            try
            {
                using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    byte[] buffer = new byte[fs.Length];
                    int bytesRead = fs.Read(buffer, 0, buffer.Length);
                    return bytesRead == fs.Length ? buffer : null;
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"文件转字节失败: {ex.Message}，路径: {filePath}");
                return null;
            }
        }

        /// <summary>
        /// 将字节数组写入文件
        /// </summary>
        public static void BytesToFile(string directory, string fileName, string fileExtension, byte[] bytes)
        {
            if (string.IsNullOrEmpty(directory))
            {
                Debug.LogError("目录路径不能为空");
                return;
            }

            if (string.IsNullOrEmpty(fileName))
            {
                Debug.LogError("文件名不能为空");
                return;
            }

            if (bytes == null || bytes.Length == 0)
            {
                Debug.LogError("字节数组为空或长度为0");
                return;
            }

            try
            {
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                string fullPath = Path.Combine(directory, $"{fileName}{fileExtension}");
                File.WriteAllBytes(fullPath, bytes);
                Debug.Log($"文件保存成功: {fullPath}");
            }
            catch (Exception ex)
            {
                Debug.LogError($"字节转文件失败: {ex.Message}");
            }
        }
        #endregion

        #region 图片处理（Texture2D/Sprite）
        /// <summary>
        /// 字节数组转Texture2D（自动识别尺寸）
        /// </summary>
        public static Texture2D BytesToTexture2D(byte[] data)
        {
            if (data == null || data.Length == 0)
            {
                Debug.LogError("图片字节数据为空");
                return null;
            }

            Texture2D texture = new Texture2D(2, 2); // 初始尺寸不影响
            if (texture.LoadImage(data))
            {
                return texture;
            }

            Debug.LogError("图片数据解析失败");
            UnityEngine.Object.Destroy(texture); // 释放无效纹理
            return null;
        }

        /// <summary>
        /// 从本地文件加载Texture2D
        /// </summary>
        public static Texture2D LoadLocalTexture(string filePath)
        {
            byte[] data = FileToBytes(filePath);
            return data != null ? BytesToTexture2D(data) : null;
        }

        /// <summary>
        /// 字节数组转Sprite
        /// </summary>
        public static Sprite BytesToSprite(byte[] data)
        {
            Texture2D texture = BytesToTexture2D(data);
            return texture != null ? Texture2DToSprite(texture) : null;
        }

        /// <summary>
        /// 从本地文件加载Sprite
        /// </summary>
        public static Sprite LoadLocalSprite(string filePath)
        {
            Texture2D texture = LoadLocalTexture(filePath);
            return texture != null ? Texture2DToSprite(texture) : null;
        }

        /// <summary>
        /// Texture2D转Sprite
        /// </summary>
        public static Sprite Texture2DToSprite(Texture2D texture)
        {
            if (texture == null)
            {
                Debug.LogError("Texture2D为空，无法转换为Sprite");
                return null;
            }

            return Sprite.Create(
                texture,
                new Rect(0, 0, texture.width, texture.height),
                new Vector2(0.5f, 0.5f) // 中心点设为中心更合理
            );
        }
        #endregion

        #region 序列化（注意：BinaryFormatter已过时，建议使用其他方案）
        /// <summary>
        /// 对象转字节数组（使用BinaryFormatter，不推荐用于生产环境）
        /// </summary>
        [Obsolete("BinaryFormatter已过时，存在安全风险，建议使用Json或Protobuf替代")]
        public static byte[] ObjectToBytes(object obj)
        {
            if (obj == null)
            {
                Debug.LogError("序列化对象不能为空");
                return null;
            }

            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(ms, obj);
                    return ms.ToArray(); // 使用ToArray()而非GetBuffer()，避免包含未使用的字节
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"对象序列化失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 字节数组转对象（使用BinaryFormatter，不推荐用于生产环境）
        /// </summary>
        [Obsolete("BinaryFormatter已过时，存在安全风险，建议使用Json或Protobuf替代")]
        public static T BytesToObject<T>(byte[] bytes)
        {
            if (bytes == null || bytes.Length == 0)
            {
                Debug.LogError("反序列化字节数组为空");
                return default;
            }

            try
            {
                using (MemoryStream ms = new MemoryStream(bytes))
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    return (T)formatter.Deserialize(ms);
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"对象反序列化失败: {ex.Message}");
                return default;
            }
        }
        #endregion

        #region 辅助方法
        /// <summary>
        /// 获取安全的写入路径（基于Application.persistentDataPath）
        /// </summary>
        public static string GetSafeWritePath(string fileName)
        {
            return Path.Combine(Application.persistentDataPath, fileName);
        }

        /// <summary>
        /// 验证协程运行器是否已设置
        /// </summary>
        private static void ValidateCoroutineRunner()
        {
            if (_coroutineRunner == null)
            {
                throw new InvalidOperationException("请先调用SetCoroutineRunner设置协程运行器");
            }
        }
        #endregion
    }
}